Next and Previous Pagination button not displaying in WordPress

You’re using a custom query (new WP_Query), so you need to pass $tyler_query->max_num_pages (the max pages) to the next_posts_link() function — more details here:

next_posts_link( null, $tyler_query->max_num_pages )

And btw, no need to echo with previous_posts_link() because the function indeed echoes the output. I.e. Just do so: <?php previous_posts_link(); ?>.

Also, you should add paged to your query args ($args):

$args = array(
    'posts_per_page' => 6,
    'paged'          => get_query_var( 'paged' ),
);

$tyler_query = new WP_Query( $args );

But if you’re using the shortcode on a single post or Page, previous_posts_link() wouldn’t work since it relies upon a global variable named $paged which is set only for archive-based requests such as search results. To make $paged works on single requests or with previous_posts_link(), you can try:

global $paged;
$paged = $paged ? $paged : get_query_var( 'page' );

$args = array(
    'posts_per_page' => 6,
    'paged'          => $paged,
);

For example, product is IOS and categories are iPhone and iMac,iPod.
So I have to display iPhone and iMac only.

So after discussing via chat (to get more details about the above), you can use the following if you want to display the name of the first two of the categories: (which could actually be just one)

$names = array();
$categories = get_the_category();
//shuffle( $categories ); // uncomment if you want random entries
foreach ( $categories as $i => $term ) {
    if ( $i < 2 ) { // show at most two
        $names[] = '<a href="' . esc_url( get_category_link( $term->term_id ) ) . '">' . $term->name . '</a>';
    }
}
$names = implode( ', ', $names );

And that would replace the $categories = get_the_category(); $names=""; if ( $categories && is_array( $categories )) { foreach ( $categories as $cat ) { $names .= $cat->name . ' '; } }.

See here for more details about get_category_link().

Additional Notes

You should call wp_reset_postdata() after your custom loop ends: while ( ... ) { ... } wp_reset_postdata();. Or after the have_posts() block ends: if ( $tyler_query->have_posts() ) { ... } wp_reset_postdata();.

Doing that would restore the global $post variable to the current post in the main query (contained in the global $wp_query variable as opposed to your $tyler_query variable). And this restoration is necessary in order for template tags like the_title() to work in terms of referencing to the current post in the main query.