Stuck in the middle
There are two places you can start when you explain something: with the thing, or with the person learning it. For example, if you're teaching a language: here's the word for apple, here's how you say you want something, now say you want an apple. Here's the word for banana, now say you want a banana – and so on. This is the method used by Michel Thomas, and it has a lot to recommend it. Instead of trying to translate people's existing knowledge into the new language, you just build new knowledge from the ground up.
On the other hand, it can be quite useful to go the other way and build on existing knowledge. Instead of having to start from zero, you can start with something familiar and teach the ways this thing is different. Michel Thomas does this also, in a small way, by teaching cognates. Most latinate languages will share a bunch of -ion words, which can save a lot of time learning vocabulary. This is especially useful if you're furthering some existing education. Rather than having to teach physics from scratch, you can start with existing mathematics knowledge and existing physical intuition.
I think part of what can make programming challenging to teach is that, for the most part, it doesn't obey rules that people are familiar with. Seymour Papert's Logo was a rare example of figuring out an existing intuition that could work in the form of physical movement. However, that's the exception, and I think in most cases programming has to be taught without leaning on many existing intuitions. In theory, this shouldn't be a big deal. Most video games teach people how to play the game in this way and do just fine. Here's crouch. Here's jump. Now jump and crouch. Great!
But the problem is that in disciplines like programming, being good at it looks like the opposite of teaching it well. When you are programming, you have some idea in your head of what you want. That is to say, you have a mental model. Then you use your programming expertise to turn that into a computational model, which you type into the computer. Writing code isn't really the hard bit, it's turning your thoughts into computer thoughts. On the other hand, to teach programming you have to go the other way. At least at first, students don't need to turn their mental model into a computer model, they need to turn the computer's model into their mental model. Rather than figuring out how to translate their existing thoughts into code, they need to learn how to think new, codey, thoughts.
This is a problem that is more apparent the less intuitive something is, which is to say how far apart the model of how it really works is from the model of how people think. Either way you have to bridge those two models to make understanding, but you suffer twice when they're far apart because the teacher has to go so far from their existing way of thinking to be able to teach. All it takes is one innocuous question, "oh, why can't I return an array from a function?" and you're suddenly zooming off into deep space, completely leaving behind the tower of knowledge you carefully built from the bottom up. I'm not convinced you can teach without a hundred diplomatic ways to say "don't ask that yet".
One thing I'm particularly unimpressed with is the power of analogies. I think analogies sound good because they carry the illusion of bridging that model gap. Truthfully, they're just some third model that vaguely overlaps both, and almost always has to make compromises to do so. The rubber sheet analogy is great, but it only really helps people who don't have to actually understand spacetime. If you learn general relativity, you learn the equations, and from the equations you can get to the rubber sheet. But you can't get from the rubber sheet to the equations. An analogy can make something unintuitive feel intuitive, but it can't make it actually intuitive.
For things where real understanding doesn't matter, and you just need some vague notion of how it works, that can be fine. And on rare occasions the thing that appears to be an analogy is actually just a more intuitive model, but to qualify for that it needs to have all the explanatory power of the old model. In many cases, though, I think analogies can do more harm than good. It's comforting to say, hey, don't worry, this new thing is kinda like some old things you recognise. But if it really isn't, all that does is encourage dragging that wrong mental model along with you long after it's become obsolete.
Instead, I think the best option is to give up on finding something that feels right and just learn the mechanics as they are. Who knows, after some time they may come to feel as natural as anything else.