A bit of software that, using some kind of standardized methodology, adds after-release functionality to a larger program; It, in a way of thinking, 'plugs in' to the program in the same way you plug a new peripheral into your computer.
The actual design behind most plugin architectures isn't too stunning, usually being nothing more that calling a specific subrouting inside of a Dynamic Link Library or a Shared Object. Programs that are in themselves executable binaries but still communicate with a program cannot technically be called plugins... but some people don't care.
If a plugin interface is done well, it will allow communication with the host program, and use of the host data, with minimal fuss. As it it, few plugin schema's do this, especially in Windows, were many times you must still set up an IPC link with the program that called you.
That having been said, plugin topology is still very useful because the plugin code executes in the programs' own thread and memory space, and so the calling program has the absolute control over the life and death of the plugin.
They also allow the designer to discard all of the other cruft that might not be necessary to a simple program, yet is still required of a standalone program; things like user interfaces, usage displays and other things that will end up being handled by the calling program.
So, to that end, that is the difference between a plugin and a program -- a program can execute by itself, whereas a plugin needs to be specially called by another piece of code that can be executed.
Can you tell what I was up all night coding?