I'm also a chess engine developer, let me answer you from my own experience:
There're lot of reasons differentiate the playing ability. Actually, a lot. This is an area where one could write a PhD thesis, but let's take a quick look at the two major factors.
- Ability to do a cutoff quicker
- Ability to evaluate a position better
Unlike a human player, a computer chess algorithm doesn't need a sophisticated position evaluation. Lots of weak engines tend to use some very complicated evaluations, such as cubic interpolation of material values but none have been proven to work. Simple is the key. Stockfish, the strongest engine in the world, has an evaluation about Elo 1800. It might sound amazing that an Elo 3000+ engine has a simple evaluation that is only about Elo 1800 level. But remember, a computer needs to use this evaluation function for hundreds of thousands of positions. The simpler, the faster the engine can search, the higher depth it can reach and therefore the more tactics it can see.
Weak engines tend to use only alpha-beta. It's insufficient because the search space is too large. One would need to consider null-move, late move reductions and other advanced algorithms.
Now, to your second point. The common mistake made by chess engines at ELO range 1500 - 1800 is that their programmer doesn't understand chess programming. MicroMax, a super light chess engine (Google it if you don't believe) can play Elo 2000. Anything weaker than it is an indication that the engine has bugs and not performing as expected, as it should.
In general, an engine with a correct material evaluation function can perform Elo 2000.