Am I using an action hook correctly?

… (although I found it strange that I didn’t need to write
activation or deactivation code…).

You don’t need activation of deactivation code unless there is something you need to do on activation or deactivation.

I tested my plugin by using a simple echo ‘fd is running’; which
strangely shows up at the top of everything – every page of the
website and even in the admin dashboard.

Plugins initialize prior to other content and your code echos data during that initialization. This isn’t surprising at all. It is exactly what should be expected.

Yes, that is how you use an action hook. That particular one doesn’t pass any variables so it is very simple.

Do I need to instantiate my code as a “plugin” per se? Isn’t it enough
to just put some PHP files in a folder in the same directory where all
the plugins are located and have them run off action/filter hooks? Or
for any sort of code to work does it need to be either a theme or
plugin?

You need to put your code somewhere that will execute. That is 1) a theme, 2) a plugin 3) a mu-plugin. The first two are most common.

1) You can drop code into your theme’s functions.php but shouldn’t unless you are the author of the theme as it will be overwritten when the theme updates.

2) No, you can’t just put code in the plugins directory. It won’t execute. You need to add the appropriate plugin headers and activate the plugin via the backend interface.

3) You can drop code into a mu-plugin file and it will just execute. This is a powerful option as the code will run for all themes and all blogs (if a network).

I’m not sure what other questions you have.