I created a new role that is identical to the Author role except that it included the "read_private_posts" and "read_private_pages" capabilities. I expected that people who were assigned the new role would then be able to view all private posts. What happened was that the new role could view private posts via direct link (i.e., permalink), but the private entries would not appear on the main page.
I tracked the issue down to get_posts() in wp-includes/query.php. Basically, there is some code there that will get the private posts if the user has "edit_private_posts". I changed this to "read_private_posts" and seem to have gained the functionality that I was looking for; I also changed "edit_private_posts" to "read_private_posts" for good measure. I have attached a patch that describes this. Is there a reason why these are "edit_" capabilities instead of "read_"?