Its highly unlikely the actual compiled executable would be ever only 20 bytes. You have normally lots of OS specific loading code, ELF headers are huge as it is.
The only way to get something running in that short a space would be a "new" compiled format which was merely the string "hello world", that could be injected directly into the parent OS, and somehow the OS just "knew" that that file was to be printed.
But then your getting into technicalities, becuase you are, by proxy, calling an entire kernel to do the real work, and that averages between 2 and 8 MB.
If your going to do something that works without an OS, then you have initialization routines you have to do just to make it work.
And then the question evolves, does "20 bytes" include or exclude the byte-code in the bios?
If you really want to do this, maybe you should have a dedicated hardware architecture, with a hard wired rom chip with the "20 bytes" of code programmed in electronically.
outside these weird technical constraints, I argue that i have my own "interpreted language", known as "cat".
"cat" is also my os, and i use it to create the initial source file
1) Coding, and compiling my bytecode:
cat > helloworld.txt
Hello World^D^D
2) Executing the "compiled" bytecode
cat helloworld.txt
Hello World
see. marvelous. I'll take the gold medal thanks :)
Only 11 bytes.
Late linux trick
$ cd /tmp
$ echo '#!/bin/echo' >> hello
$ chmod u+x hello
$ ./hello world
> ./hello world
$ wc -c ./hello
> 12 ./hello