This is an old topic and I'd like to add my understanding here to expand the knowledge of this interesting topic.
The key difference between REM and :: is:
REM is a command itself, while :: is NOT.
We can treat :: as a token that as soon as CMD parser encounters the first non-blank space in a line is this :: token, it will just skip the whole line and read next line. That's why REM should be followed by at least a blank space to be able to function as a comment for the line, while :: does not need any blank space behind it.
That REM is a command itself can be best understood from the following FOR syntax
The basic FOR syntax is as follows
FOR %v in (set) DO <Command> [command param]
here <Command>
can be any valid command
So we can write the following valid command line as rem
is a command
FOR %i in (1,2,3) DO rem echo %i
However, we CANNOT write the following line as ::
is not a command
FOR %i in (1,2,3) DO :: echo %i