Previously, whenever we have instanced a scene from code we've needed to use the preload() function. Why is it that in Spell.gd script we instance the bullet scene without using preload? Is it because we are exporting the variable and when we drag it into the inspector it's automatically preloading? If so, is there a reason we haven't been doing this everywhere?
Yes. Using preload() returns a PackedScene object. An exported TSCN file is a PackedScene object. So an exported TSCN is a preloaded scene, just one you choose using the inspector instead of code.
As for why it's not used everywhere, sometimes you don't have more than one TSCN to instance, or you have a very specific set of TSCN files you want to be loaded, and you don't have any reason to allow them to change. Then it just makes more sense to use preload() in code than it is to have to define variables and change them there.