Related posts are a really cool feature that can help increase pageviews on your blog. Most people don't know how to add related posts so they do the typical WordPress thing, install a crappy plugin. I can tell you that if you're using the YARPP plugin, it's only a matter of time before your database gets bloated, your site slows down, and maybe even grinds to a halt.
You don't need all the extra junk that comes with a plugin to display related posts. You just need one simple function that queries posts with the same tag(s) or category of the current post and outputs links in a list. There is no reason to be adding things to the database.
There are two functions in the embedded gist below. The first one is the jt_related_posts() function which will show related posts by category. The second one should only be used inside genesis themes, I'll talk more about it later.
The jt_related_posts() function should be placed in your functions.php file. After placing the function in functions.php you can then call the function inside your templates. Specifically you should call the function (and echo it) somewhere after the_content() in your single.php file.
The function takes 2 arguments (title and count). The arguments are optional and default to "Related Posts" for the title and 5 for the number of related posts to be displayed.
You could call it like this echo jt_related_posts(); for the default. If you wanted it to show up on something like a custom post type of "portfolio", you could call it like this inside of single-portfolio.php echo jt_related_posts('See more client sites', 3);, which would show the custom title you passed in and 3 posts.
Notice that this function will first look for posts sharing the same tag. If it doesn't find any shared tags it will show posts in the same category, if no posts share the same tag or category, no related posts will be shown.
Also notice that this function uses get_posts() which grabs an array of posts. That means there is no need to use wp_reset_postdata() or wp_reset_query(). We're not creating a new query object or customizing the main query. We're simply (and non obtrusively) grabbing an array of posts and outputting their links in an unordered list.
Now about that other function do_jt_related_posts(). That function can be used inside Genesis themes. It automatically executes the related posts function after a post using a genesis hook (genesis_after_post_content). Doing it this way means you don't have to put it inside the single.php template and allows you to add some extra logic in that can stay inside of functions.php where it belongs, not inside of a template.
It's obviously okay to call functions inside your template, but if you see a template that has a bunch of code in it handling logic then you're doing it wrong. Functions and logic should be inside functions.php. You call the functions inside of your templates. Templates are for structuring html and putting content in the right places, not for handling a bunch of logic for functions.
Why is it bad to put logic inside of templates? Multiple reasons. It makes your site harder to edit (the logic isn't in one place), it makes your templates ugly and difficult to work with. Just remember templates are for html and calling functions, not really for creating them. Besides that, a function inside of functions.php can be used in any template, so there is no need to go rewriting a function in each template.