The biggest difference is that the first way appends to existing contents, whereas the other two fill an empty vector. :)
I think the keyword you are looking for is return value optimization, which should be rather common (with G++ you'll have to turn it off specifically to prevent it from being applied). That is, if the usage is like:
vector<int> vec = fill_vector();
then there might quite easily be no copies made (and the function is just easier to use).
If you are working with an existing vector
vector<int> vec;
while (something)
{
vec = fill_vector();
//do things
}
then using an out parameter would avoid creation of vectors in a loop and copying data around.