I've achieved this using a view to pull nodes that share the same taxonomy as your current node.
Basically create a view that uses the 'Has taxonomy term' contextual filter. And also include a content NID contextual filter to exclude the current node (in the list appearing in that view).
Follow the example here to create the view ('Views 3' steps at top):
http://www.metachunk.com/blog/adding-related-content-view-drupal-7
I've also taken it a bit further and ticked 'Reduce Duplicates' and 'More > Allow multiple values'. That way you can specify multiple terms from your current node and only get a node once if it appears in more than one term.
Make sure you select the fields you'd want to see in your template.
My view is also filtered to one content type 'news' so i've named it 'related_news'. I use the following code in my template.php to grab the views content and pass the template an array. Add your custom fields to the $terms array to then use their ID to find related content.
/**
* Return result of Related News view for a specific node.
* TO-DO: Add default functionality.
* @param object $node
* @return array
*/
function [template]_get_related_news($node) {
$terms = array();
//Get terms from fields.
$terms = array_merge($terms, $node->field_field_term_1);
$terms = array_merge($terms, $node->field_field_term_2);
//Build array of ids
$termIDs = array();
foreach ($terms as $terms){
$termIDs[] = $terms['raw']['tid'];
}
//Load view
$relatedView = views_get_view('related_news');
//Execute view with term ids as argument. Include node id to exlude it from results
$relatedView->set_arguments(array(implode('+', $termIDs), $node->nid));
$relatedView->execute();
return $relatedView->result;
}
You could also get the view to produce a block and use this to display the content within your theme.