An ultrasonic sensor just tells you the distance to the nearest reflecting object that is within range, so using this to determine whether there was a person in the room would require you to perform a three-dimensional scan of the room and then compare that against the results of the same scan when the room was empty. As long as the person was close enough to the sensor to be detected, and was not hidden behind something else, they could be detected. But it would require quite a complex scanning process and more data than a typical Arduino could hold in memory, to perform it.
Not true at all, it would be quite easy because of the wide detection pattern of an ultrasonic sensor. A few along one wall would be all that's required. The memory would be almost nothing, and it would NOT be 3D by any stretch of the imagination. There are people that use 15 sensors with my library with no problems at all.
The sort of PIR sensors used in security lights and alarm systems are very good at detecting people moving within a room and can detect even very small movements. As long you don't need to detect the presence / absence very promptly, and a 'false negative' (reporting the room was empty when it wasn't) was tolerable, that seems the most practical approach. The idea would be that the room was assumed to be empty if no movement had been detected for some time - for example, five minutes.
They only detect movement. If the person is not moving, the room would be "empty". Ultrasonic sensors would detect someone in the room, even if not moving.
You don't count visitors entering the room, that's just a trigger to scan the room. A room scan would be done every so often. You could even do it with one sensor mounted to a servo that scanned the room.
Using sonar is only difficult to those who have not used it. If you know the distance to the other wall, you simply ping and if you get a result close to the wall distance there's nothing in the way. If you get a "no ping" result it means that there's something in the room that absorbed the ping. If you get a distance that's smaller than the distance to the other wall, it means there's someone in the room. It's all quite easy and requires just a few lines of code.
I actually have designed something like this. On power up, each of the ultrasonic sensors send a series of pings and average the results. This is stored for each sensor as the wall distance. It then pings every so often (can be multiple times a second if you like). If the ping result is 0 "no ping" or anything less than the calibrated initialization distance, you know there's something in the room. I always do a second (or third) ping to then confirm the results.
Ultrasonic sensors are accurate to within 1cm so someone could try to "hide" by hugging the wall and not moving and they would still be detected. The sensors also very cheap, can be communicated with using only one wire, and are super easy to write a sketch to communicate with. Nothing to invent, unsolder, or anything like that. Just connect, drop in an example sketch, tweak it a bit, and you're ready to go.
The IR retina reflection is a great idea, but a much more challenging build. Sounds like a great project, but maybe not a great first project. There's probably a lot of trial and error and filtered logic that needs to be worked on for it to be effective.