Here's how I would explain it:
In higher-level languages, variables represent abstract things, and it's up to the language to decide how to actually represent them in bits and push the bits around to act on those things. It makes sense to allow a variable to represent the concept of "nothing".
C is not like that. C variables are actual collections of bits stored in memory. What they represent is up to the programmer. It makes no sense for a C program to have a variable of type "nothing"--that would mean "allocate no bits of memory", and it wouldn't know what to do with that. In C, "int" means "allocate 32 bits of memory", "int *" means "allocate memory sufficient to hold a memory address, and when I dereference it, get 32 bits at a time". "Void *" means "allocate memory for a memory address, and I'll tell you later how many bits to fetch from there".
A "void" function return type in C means "return from the function, but don't pass any bits to the caller". In a higher-level language like Python, for example, "return None" means return to caller, and pass it some collection of bits that represents the abstract concept of 'nothing'", which is a different thing.