A WordPress theme should only contain that which relates to the look and feel of the site. Any core functionality belongs in a plugin.
A good rule-of-thumb is that anything a user would expect to keep after changing themes belongs in a plugin. This includes custom post types, taxonomies, custom metaboxes, shortcodes, and customizations to other plugins (like my Display Posts Shortcode snippets).
For specific functionality that’s reusable and/or the client might want to selectively disable, it’s best to build as its own plugin, like BE Events Calendar.
For everything else that’s project-specific but should be theme-independent, I put in a plugin called Core Functionality. Feel free use this as a starting point for your own core functionality plugin.