EDIT: I'm adding a summary of my point at the top, for easier reading:
If your method is returning multiple pieces of data that are logically all part of the same "thing", then definitely compose them into a complex object regardless of whether you are returning that object as the return value or an output parameter.
If your method needs to return some kind of status (success/failure/how many records updated/etc.) in addition to data, then consider returning your data as an output parameter and using the return value to return the status
There are two variations of the situations to which this question applies:
Needing to return data that consists of multiple attributes
Needing to return data along with a status of the action used to obtain that data
For #1, my opinion is that if you have data consisting of multiple attributes that all go together, then they should be composed into a single type as a class or struct, and a single object should be returned as either the return value of a method or as an output parameter.
For #2, I think this is the case where output parameters really make sense. Conceptually, methods typically perform an action; in this case, I prefer to use the return value of the method to indicate the status of the action. That could be a simple boolean to indicate success or failure, or it could be something more complicated such as an enum or string if there are multiple possible states to describe the action that the method performed.
If using output parameters I would encourage a person to use only one (refer to point #1), unless there is a specific reason to use more than one. Do not use multiple output parameters simply because the data you need to return consists of multiple attributes. Only use multiple output parameters if the semantics of your method specifically dictate it. Below is an example where I think multiple output parameters make sense:
// an acceptable use of multiple output parameters
bool DetermineWinners(IEnumerable<Player> players, out Player first, out Player second, out Player third)
{
// ...
}
Conversely, here is an example where I think multiple output parameters do not make sense.
// Baaaaad
bool FindPerson(string firstName, string lastName, out int personId, out string address, out string phoneNumber)
{
// ...
}
The attributes of the data (personId, address, and phoneNumber) should be part of a Person object returned by the method. A better version of it would be the following:
// better
bool FindPerson(string firstName, string lastName, out Person person)
{
// ...
}