It's not a joke, I could not stand to have this happen a fourth time, it's impacting me mentally.
This line is important, because it shows that you feel it is time to change. It shows that you recognize this as a pattern, and would like the pattern to stop. That desire is probably the most important part of the solution. Fixing these sorts of situations often involves changing the way you, yourself, think. It's impossible for someone to do that for you, so your desire to change will be the one thing that makes the change happen.
For some background, I've been in similar "too good at coding for my job" situations before, though never to the degree you describe. I could cure cancer with template metaprogramming in C++, but many whom I work with are barely versed in the basics of Object Oriented Design. I wrote code which abused SFINAE and pushed right up against the exact wording of the C++ specifications, when many projects I worked on were still using antiquated and buggy versions of gcc. My approach was simply to show them just how amazing these tools are, and all the problems it could solve. I loved explaining little programming tips to people, and they largely enjoyed it.
Does that sound familiar?
"Yes, but one should have a good level to understand [Mik's code] because components are intelligently decoupled."
Consider this statement from a risk based perspective. Your boss needs to keep things going, no matter what. If you leave to go chase some awesome job opportunity, your boss still has to make sure the code gets maintained. What your coworker just said was that, if they have to replace you, they need to find a very skilled coder, because anyone who isn't that good will not be able to maintain it. This is a risk. What if they can't find a good enough developer, or can't afford to pay them enough?
You may have produced what you would call "good code," but the definition of "good code" is very much dependent on the context. What is "good code" at Google, with their cutting edge ways of thinking, may be very bad code for someone working at the FAA, who is predominantly concerned with reliability rather than keeping up with the cutting edge. Your boss' definition of "good code" includes the ability to maintain it in all sorts of situations, including without you. If your coworkers are not comfortable maintaining your code, then you are suddenly a liability to the company, because you produce product which they cannot maintain if you decide to go elsewhere.
From this perspective, one may argue that you are forcing them to accept your definition of "good code." Instinctively, this may appear to be a good thing, but it is fraught with difficulty, such as this risk based way of thinking which you may not have been thinking of.
We have a phrase, "putting the cart before the horse." One of the many meanings associated with it is putting the content you care about most (being able to use your advanced techniques) over the forces which should be pulling it forward (your coworker's understanding of these techniques). You've written the code in this advanced style, and then encouraged the other developers to "catch up" to this style. This can be effective, but if anything happens to you before they "catch up," the company is suddenly at risk because nobody can maintain the code.
How can I avoid this in the future?
Fixing this can be a terribly hard thing to do because it involves approaching the problem in a different way than you are typically comfortable. Instead of first writing code in this advanced style, and then teaching your coworkers how to think that way, you should flip it around. Teach your coworkers to like that style of coding, and then start writing code in that style. It may seem backwards, but its much more stable. From a boss' perspective, there's little to no risk from the team learning to code better. Once they code better, the style you want to develop in is suddenly less risky.
In the mean time, you will have to write code which, by your standards, is "less good," but that's okay. Your code is not your only product here. Your other product is helping teach the other developers, and the value of that can easily exceed the value of writing "perfect code."
Of course, it can be hard to tell when it's safe to write code in the style you want to write in. If it was easy to tell, you'd certainly have figured it out by now! One powerful technique you can use is to let others push for the advanced coding styles, rather than pushing for it yourself. It's one thing to teach someone the difference between inheritance and composition. It's an entirely different thing to teach them well enough that they advocate changing your existing codebase to be more clear in when it uses them. The latter case really lets you know that not only do they get the concept, but truly embrace it.
One ideal for teaching such concepts is to teach nothing. Let the students discover something, and then you point them in a direction that discovery can go. Maybe one of them discovers something neat about inheritance and you can point them towards the Visitor design pattern based on what they discovered. Don't just give them Visitor, but give them a sense of direction so that they can go out and find Visitor themselves.
It's a much more difficult approach, and you'll certainly want to find a happy medium between that and your current approach, but it can be very rewarding. More importantly for your answer, it can provide value to the company without the risk. If you are providing value to a company, and not putting the company at risk, you will virtually never get laid off. And in the few cases where you can still get laid off, management will provide a reason for it (such as a downturn in the economy, or a shift in direction of the company). If you do it very well, you'll find that management instead will start shaping your path, just as you shape your coworkers, and you'll find a curious tendency for you to have learned just the right skill just when they need it most.