This is one of those questions that doesn't have a single correct answer. If you go back in time when 8bit machines ruled the gaming world, most of the code could not be ported directly to work on another platform. We wrote pure assembly code, being close to bare metal. The code was tightly bound to the hardware and it wasn't really worth trying to use for example C, because it was very unlikely compiler would do better job that human. This way most of such written code couldn't be reused. Porting game to different platform meant rewriting it.
Times changed. Compilers became smarter, CPUs became faster. It made possible to use higher level languages like C. Still, the code and the machine were tightly coupled, but big chunks of such code could be reused for next, usually similar game. This gave birth to very first engines. It's worth noting that word 'engine' appeared lot later. It's not known who said "engine" very first time, but it's dated to early 90s. It means that probably the development of first 3D games and mostly contribution of Quake and Unreal made word 'engine' the term we know today. It doesn't mean there were no 'engines' before that time. After all SCUMM today is also called "the engine". It's just in 80s nobody used this word to describe certain set of functions.
So what the engine is?
Historically, it's reusable piece of software that delivers all major subsystems to built a game on top of it. How was it different from framework? Well, it wasn't. Many engines are also frameworks and vice versa. It's just term that became popular in video games but describing something that was already well known anyway ( like recently ECS ;) ). We could call engine any 'common code' that implements basic low-level subsystems (graphics, input, sound, resource handling, memory management, scripting, etc.) that has been reused in at least one game. Was "Wolfenstein3D" engine? It was never named, but the code was reused in several titles ( including weird case of "Super 3D Noah's Ark" ). I mentioned SCUMM already. Reused code could be improved for the next game, but it was still same code base.
Today we look at it little different. We see engine as some sort of player. There's set of libraries and tools. We do not fiddle with the actual engine. We create content that will play when loaded by the 'player'. For example Unity is such a player. This may also give us distinction between engines and frameworks. One might say, framework doesn't limit you, doesn't close programmer in hermetic environment. We may consider Ogre3D to be a framework. Some engines are also frameworks in that matter.
Defining the word "Engine" isn't simple, because everyone may understand it different way - and it's all correct. But at the core I think those old titles tell us, what engine should have, because otherwise nobody would call IdTech or Unreal "The Engine" back then ;)