Consider this function:
Thing func(){
return something;
}
Every call to this function, a copy of something
is made and passed
If you're returning a non-static local variable, then you must return by value, since it will be destroyed when the function returns, making any references to it invalid. In that case, the copy can often be replaced by a move, or elided altogether.
If you're returning something persistent, then you're right; it's generally better to return a reference and let the caller decide whether it should be copied. But there might be other reasons such as thread safety to prefer returning by value even then: by returning a copy, the reader can't access the persistent object while another thread might be modifying it.