I think there's a lot of semantic confusion and industry vagueness going on here - not about OP, more about software generally.

- "Virtual machine" is a term that means a lot of things in different contexts. Your last example refers to hardware or operating system virtualization (VMWare, Docker, things of that nature). These VMs are intended to replicate a full computer system as a subprocess of another (physical) computer system. Typically this is not about replicating the direct hardware details: it would be odd to have an Ubuntu VM with 4GB of RAM directly specified. Rather there is a general Ubuntu VM and the user allocates 4GB of their own memory to the virtualization process.

- "Virtual machine" is also widely used for application
virtualization: the Java virtual machine, for instance, and ScummVM. These VMs are not intended to replicate a full computer and exist to run applications in a way that abstracts away the hardware implementation details. For your second point, "VM" is arguably misapplied to things like JVM and Python VM, but I think the analogy is still useful, and regardless that battle was lost 40 years ago.

In practice "Application Virtual Machine" is taken to mean "compiler or interpreter for general purpose non-native code" but this does not have to be the case. There is nothing inherent about using a more limited set of instructions. Going left-right in terms of processor-level instructions, all of the following can be described as actions using VMs:

using Xen to virtualize a Unix machine - running Debian in Docker - running a web server in Java - scripting in Python - Day of the Tentacle

- An "emulator" is a computer program that models the hardware of another computer system and executes machine language written for that system. An emulator typically carries the hardware specifics of the system it is emulating - in industry emulators are widely used to test new hardware without having to waste physical resources, so having an exact replica is important. For gaming, I suppose it could make sense to double the RAM in an N64 emulator to reduce performance bottlenecks, but it wouldn't be a faithful emulation and would probably be nontrivial to implement without breaking existing games.

I agree that the differences between these are fuzzy. In some sense you can think of an "emulator" as an application virtual machine whose bytecode is the machine language of the hardware the emulator is emulating. I would go so far as to say there isn't a theoretical difference. In practice, the difference is that emulators are used to faithfully run existing compiled applications, including all the unreliable quirks - an emulator that fixes bugs which exist in the hardware is not a good emulator. Application VMs are used to reliably execute new applications (including updates designed to remove unreliable quirks). The use cases and requirements are different enough that I don't think there's much actual confusion.

In another sense emulators are performing hardware/operating-system virtualization into the older system. I think the most salient point is the importance of preserving existing hardware in an emulator. Theoretically you could see someone creating a VM image for KERNAL that can run Commodore 64 8-bit processes on a 64-bit architecture with an arbitrary amount of RAM. But in practice emulators that carry the C64's hardware restrictions are much more useful, since people writing code for C64 hardware typically want to run it on an actual C64.

As one last incredibly pedantic note: there is also genuine fuzziness between OS VMs and application VMs. You can think of the JVM or Python VM as "emulating" a hypothetical processor architecture with Java/Python primitives as fundamental machine-level operations - there used to be physical LISP machines designed like this. Since Java and Python are Turing complete and their bytecode sort of resembles a very verbose assembly, I think the analogy is in fact useful. But this analogy also extends to ScummVM - think of a hypothetical LucasArts arcade cabinet where SCUMM primitives are hard-coded into the processor.