Show all 12 months regardless they have posts

I believe this is correct:

$year = 2013;
$month = 0;
$qry = new WP_Query(
  array(
    'post_type'=>'post',
    'posts_per_page'=>-1,
    'orderby'=>'date',
    'order'=>'ASC',
    'ignore_sticky_posts' => true,
    'year' => $year,
  )
);

while ($month < 12) {
  $month++;
  echo date('M',strtotime('2000-'.str_pad($month, 2, '0', STR_PAD_LEFT).'-01 00:00:01')).'<br>';
  if ($qry->have_posts()) {
    while ($qry->have_posts()) {
      if (date('n',strtotime($qry->post->post_date)) == $month) {   
        echo " -- ";
        the_title();
        echo '<br />';
        $qry->the_post();
      } else {
        break;
      }
    }
  } 
}

Of course, you will need to set your $year to the year you actually want.

That should Loop through all twelve months, echoing each one, checking for posts that match in the $qry results.

To print only the month names and links to months having posts.

$year = 2013;
$month = 0;
$qry = new WP_Query(
  array(
    'post_type'=>'post',
    'posts_per_page'=>-1,
    'orderby'=>'date',
    'order'=>'ASC',
    'ignore_sticky_posts' => true,
    'year' => $year,
  )
);

$months = array();
if (!empty($qry->posts)) {
  foreach ($qry->posts as $p) { 
    $months[date('n',strtotime($p->post_date))] = $p->post_date;
  }
}

while ($month < 12) {
  $month++;
  $monthname = date('M',mktime(0,0,0,$month,1,$year));
  echo '<li>';
    if (isset($months[$month])) {
      echo '<a class="year" href="'.get_month_link($year,$month).'" />'.$monthname.'</a>'.'<br>';
    } else {
      echo $monthname.'<br>';
    }
  echo '</li>';
}